#include "../util/Trace.hpp"
#include "../util/poll_manager.hpp"
#include "../transport/transport_kcp.hpp"


#include <boost/make_shared.hpp>
#include <boost/smart_ptr.hpp>
#include <memory>
#include <unistd.h>
#include <string>


bool UDP_write(TransportUDPPtr transport, unsigned char* buffer, uint32_t size)
{


	buffer;
	uint32_t write_size = size;
	uint32_t write_sent = 0;
	bool has_write_callback = true;

	//writeUDPTransport();
	bool writing = true;
	bool can_write_more = true;


	transport->enableWrite();
	while(has_write_callback && can_write_more)
	{


		uint32_t to_write = write_size - write_sent;	
		//ROS_DEBUG_NAMED("superdebug", "Connection Client Writing %d bytes", to_write);
		//INFO("[INFO] superdebug Connection Client Writing ", to_write, " bytes");
		uint32_t bytes_sent = transport->write(buffer+write_sent, to_write);
		//ROS_DEBUG_NAMED("superdebug", "Connection Client Wrote %d bytes", bytes_sent);
		//INFO("[INFO] superdebug Connection Client Wrote ", bytes_sent, " bytes");


		if(bytes_sent<0)
		{
			writing = false;
			return false;	
		}
		write_sent += bytes_sent;

		//INFO("[INFO] superdebug Connection Client total Wrote ", write_sent, " bytes");

		if(bytes_sent < (int)write_size - (int)write_sent)
		{
			can_write_more = false;	
		}

		if(write_sent == write_size)
		{
			//buffer.reset();
			write_sent = 0;
			write_size = 0;
			has_write_callback = 0;	
		}
	}

	if(!has_write_callback)
	{
		transport->disableWrite();	
	}
//	buffer.reset();
	writing = false;

	return true;
}

void checkForShutdown()
{

}

//void UDP_write(boost::shared_array<uint8_t>& buffer, uint32_t size)
int main(int argc, char *argv[])
{
  //INFO("[INFO] start PollManager.. loading...");
  PollManager::instance()->addPollThreadListener(checkForShutdown);
  PollManager::instance()->start();
  //INFO("[INFO] start PollManager.. ok...");
  

  //INFO("[INFO] create udp_transport...");
  PollSet poll_set;
  TransportUDPPtr udp_transport; 
  udp_transport = std::make_shared<TransportUDP>(&PollManager::instance()->getPollSet());
  //INFO("[INFO] ok!");


  int cnt = 0;

	//uint8_t tmp[20] = "Hello World:";
	//boost::shared_array<uint8_t> buffer(tmp);
  unsigned char buffer[1024];

  //INFO("[INFO] connect...");
	if(!udp_transport->connect("127.0.0.1", 8080,  "127.0.0.1", 9090, 300, false))
  {
    INFO("[INFO] KCPClient connect failed");
    INFO("[BREAK]");assert(0);//ROS_BREAK
  }
  //INFO("[INFO] KCPClient connect successfully");

	while(true)
	{
    //create buffer
    //sprintf(reinterpret_cast<char*>( buffer.get()), "HelloWorld:%d",  cnt++); 
    //sprintf((char*)buffer, "HelloWorld:%d",  cnt++); 
    sprintf((char*)buffer, "%d",  cnt++); 

    int size = sizeof(buffer);

    //INFO("[DEBUG] buffer:", buffer ," size:", size);
    //INFO(buffer );
    std::cout<<buffer<<std::endl;

 	 	if(UDP_write(udp_transport, buffer, size)==false)
		{
			INFO("[INFO] UDP_write failed!");
			break;
		}
    //0.0002s, 0.2 ms, 200  us
    usleep(20000);
	}
	
//-----------NOTE: UDP_write()
  //INFO("[INFO] shutdown PollManager...loading...");

  PollManager::instance()->shutdown();

  //INFO("[INFO] shutdown PollManager...ok!");



  return 0;
}
